home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #2 / Ham Radio 2000 - Volume 2.iso / HAMV2 / TCP_IP / TNOS230S / LOOK.C < prev    next >
C/C++ Source or Header  |  1997-09-06  |  7KB  |  262 lines

  1. /* Peek into a user's actions on the bbs.
  2.  * This allows you to follow all stuff, and also
  3.  * send messages and initiate chats...
  4.  * (C) 1994, Johan. K. Reinalda, WG7J
  5.  */
  6. #include "global.h"
  7. #ifdef LOOKSESSION
  8. #include "ctype.h"
  9. #include "commands.h"
  10. #include "session.h"
  11. #include "smtp.h"
  12. #include "usock.h"
  13. #include "mailbox.h"
  14.   
  15. #if !defined(_lint)
  16. static char rcsid[] OPTIONAL = "$Id: look.c,v 1.17 1997/09/07 00:31:16 root Exp root $";
  17. #endif
  18.  
  19. static void look_input (int unused,void *p1,void *p2);
  20. extern int sockblock (int s,int value);
  21.   
  22. struct look {
  23.     struct session *sp;     /* our look session */
  24.     int user;               /* socket we look at */
  25. };
  26.   
  27.  
  28. int
  29. dolook(int argc OPTIONAL, char *argv[],void *p OPTIONAL)
  30. {
  31. struct look lk;
  32. struct usock *up;
  33. int chat;
  34. char *cp;
  35. char const *cp2;
  36. char name[20];
  37. char buf[MBXLINE];
  38. int i, block;
  39.   
  40.     /* Check if this comes from console - WG7J*/
  41.     if (Curproc->input != Command->input)
  42.         return 0;
  43.   
  44. #ifdef MAILBOX
  45.     /* Find the user ! */
  46.     lk.user = atoi (argv[1]);  /* store socket #, or illegal # if callsign */
  47.     for (i = 0; i < NUMMBX; i++)    {
  48.         if (Mbox[i] == NULLMBX)
  49.             continue;
  50.         if (!stricmp (Mbox[i]->name, argv[1]))
  51.             break;
  52.         if (lk.user && Mbox[i]->user == lk.user)
  53.             break;
  54.     }
  55.     if (i != NUMMBX) {
  56.         lk.user = Mbox[i]->user;
  57.         strncpy (name, Mbox[i]->name, 20);
  58.     } else {
  59. #endif
  60.         lk.user = atoi (argv[1]);
  61.         sprintf (name, "socket %d", lk.user);
  62. #ifdef MAILBOX
  63.     }
  64. #endif
  65.   
  66.     if ((up = itop (lk.user)) == NULLUSOCK)    {
  67.         tputs ("User socket error!\n");
  68.         return 0;
  69.     }
  70.     if (up->look)    {
  71.         tprintf ("Already looking at %s\n", argv[1]);
  72.         return 0;
  73.     }
  74.     if (lk.user == Curproc->input || lk.user == Curproc->output)    {
  75.         tputs ("Can not look at myself!\n");
  76.         return 0;
  77.     }
  78.     /* Now everything seems okay ! Get a session */
  79.     if ((lk.sp = newsession (name, LOOK, 1)) == NULLSESSION)    {
  80.         tputs (TooManySessions);
  81.         return 0;
  82.     }
  83.   
  84.     up->look = Curproc;     /* Tell the socket to echo data to this process ! */
  85.     chat = 0;
  86.     block = sockblock (Curproc->input, SOCK_NORXBLOCK);
  87.   
  88.     tprintf ("%s session %d looking at %s\n", Sestypes[lk.sp->type], lk.sp->index, argv[1]);
  89.   
  90.     /* Process whatever's typed on the terminal */
  91.     memset (buf, 0, MBXLINE);   /* Clear the input buffer */
  92.     while (nb_recvline (Curproc->input, (unsigned char *) buf, sizeof(buf) - 1) >= 0) {
  93.         if (itop (lk.user) == NULLUSOCK)
  94.             break;
  95.         if (buf[0] == '/')    {
  96.             cp = skipnonwhite (buf);
  97.             cp = skipwhite (cp);
  98.             /* process commands */
  99.             switch (tolower (buf[1])) {
  100.                 case 'h':
  101.                 case '?':
  102. #ifdef MAILBOX
  103.                     tputs ("<Cmds>: /c-chat /i-insert /m-msg /q-quit\n");
  104. #else
  105.                     tputs ("<Cmds>: /q-quit\n");
  106. #endif
  107.                     break;
  108. #ifdef MAILBOX
  109.                 case 'm':   /* Send a message to the user */
  110.                     if (i == NUMMBX)          /* Not a mailbox user */
  111.                         break;
  112. #if 0
  113.                     cp = &buf[2];
  114.                     if (buf[2] == ' ')
  115.                         cp = &buf[3];
  116. #endif
  117.                     usprintf (lk.user, "<sysop>: %s", cp);
  118.                     break;
  119.                 case 'c':   /* Initiate chat mode */
  120.                     if (chat || i == NUMMBX)
  121.                         /* Already in 'chat' mode or not a mailbox user */
  122.                         break;
  123.                     (void) usputs (lk.user, "*** SYSOP Initiated CHAT.\n");
  124.                     up->look = NULL;    /* Disable echoing in socket layer */
  125.                     /* Now we need to redirect the network input
  126.                      * from the user's bbs process to the chat process
  127.                      */
  128.                     lk.sp->proc1 = newproc ("CHAT Server", 1024, look_input, 0,
  129.                         (void *)&lk, NULL, 0);
  130.                     chat = 1;
  131.                     break;
  132. #endif
  133.                 case 'i':
  134. #if 0
  135.                     cp = skipnonwhite (buf);
  136.                     cp = skipwhite (cp);
  137. #endif
  138.                     up->insertptr = up->insertbuf = strdup (cp);
  139.                     (void) usputs (lk.user, cp);
  140.                     break;
  141.                 case 'b':
  142.                 case 'e':
  143.                 case 'q':   /* quit chat mode, or look mode */
  144. #ifdef MAILBOX
  145.                     if (!chat)
  146.                         goto done;
  147.  
  148.                     lk.sp->proc1 = NULLPROC;
  149.                     up->look = Curproc; /* Enable echoing in socket layer */
  150.                     (void) usputs (lk.user, "*** BACK in mailbox\n");
  151.                     kpause (500);
  152.                     kwait (NULL);    /* wait for the death of look_input */
  153.                     chat = 0;
  154. #else
  155.                     goto done;
  156. #endif
  157.                     break;
  158.                 default:
  159.                     break;
  160.             }
  161.         }
  162. #ifdef MAILBOX
  163.         else if (chat)
  164.             usprintf (lk.user, "<sysop>: %s", buf);
  165. #endif
  166.   
  167.         usflush (lk.user);
  168.         usflush (Curproc->output);
  169.         memset (buf, 0, MBXLINE);   /* Clear the input buffer */
  170.     }    
  171. done:
  172.     (void) sockblock (Curproc->input, block);
  173.     /* A 'close' command was given, or user disconnected.
  174.      * Notify the user, kill the receiver input task and wait for a response
  175.      * from the user before freeing the session.
  176.      */
  177.     cp2 = sockerr (lk.sp->input);
  178.     tprintf ("\n%s session %u closed: %s\n", Sestypes[lk.sp->type], lk.sp->index,
  179.         (cp2 != NULLCHAR) ? cp2 : "EOF");
  180.   
  181.     if ((up = itop (lk.user)) != NULLUSOCK)   /* Make sure socket is still there */
  182.         up->look = NULL;
  183. #ifdef MAILBOX
  184.     if (lk.sp->proc1 != NULLPROC) {
  185.         /* kill the receive process */
  186.         lk.sp->proc1 = NULLPROC;
  187.         if (up) {
  188.             (void) usputs (lk.user, "*** BACK in mailbox\n");
  189.             usflush (lk.user);
  190.         }
  191.     }
  192. #endif
  193.     (void) keywait (NULLCHAR, 1);
  194.     freesession (lk.sp);
  195.     return 0;
  196. }
  197.  
  198.   
  199. #ifdef MAILBOX
  200. /* Task that read the user's input socket (that formerly went to the socket
  201.  * process), and sends it to the look session !
  202.  */
  203. void
  204. look_input(unused,p1,p2)
  205. int unused OPTIONAL;
  206. void *p1;
  207. void *p2 OPTIONAL;
  208. {
  209. struct session *sp;
  210. struct usock *up;
  211. int user,c;
  212. int block;
  213. int done = 0;
  214.  
  215.     sp = ((struct look *)p1)->sp;
  216.     user = ((struct look *)p1)->user;
  217.  
  218.     if ((up = itop (user)) == NULLUSOCK) {
  219.         /* Make sure our parent doesn't try to kill us after we exit */
  220.         sp->proc1 = NULLPROC;
  221.         return;
  222.     }
  223.  
  224.     /* Suspend the process that owns the socket */
  225.     suspend (up->owner);
  226.  
  227.     /* Get current blocking mode and set to non-block */
  228.     block = sockblock (user, SOCK_NORXBLOCK);
  229.  
  230.     /* Process input on the users socket connection */
  231.     while (!done)    {
  232.         while ((c = recvchar (user)) == EOF)    {
  233.             if (errno != EWOULDBLOCK || sp->proc1 == NULLPROC)    {
  234.                 done = 1;
  235.                 break;
  236.             }
  237.             kpause (500);
  238.         }
  239.         if (!done)
  240.             tputc ((unsigned char)c);
  241.     }
  242.     if (sp->proc1 != NULLPROC)
  243.         tputs ("*** Remote user disconnected!\n");
  244.  
  245.     /* Reset to original blocking mode */
  246.     (void) sockblock (user, block);
  247.  
  248.     /* Make sure our parent doesn't try to kill us after we exit */
  249.     sp->proc1 = NULLPROC;
  250.  
  251.     /* Alert the parent, in case the chat was terminated by losing the
  252.      * user connection. This in effect will close the look session
  253.      */
  254.     alert (sp->proc, ENOTCONN);
  255.  
  256.     /* Resume the process that owns the socket */
  257.     resume (up->owner);
  258. }
  259. #endif /* MAILBOX */
  260.   
  261. #endif /* LOOKSESSION */
  262.